﻿using NetSDKCS;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using CaseManagerLibrary.Models;
using CaseManagerLibrary.Log;
using PSDLib;

namespace PSDLib.Download
{
    public class DH_EVS_Downloader : IDownloader
    {
        //private DownloadServiceContext context;
        public IntPtr m_LoginID { get; set; } = IntPtr.Zero;
        public NET_DEVICEINFO_Ex m_DeviceInfo { get; set; }
        private IntPtr m_DownloadID { get; set; } = IntPtr.Zero;

        private fTimeDownLoadPosCallBack m_DownloadPosCallBack;
        public string Id { get; set; }
        //public string ServerIP { get; set; }
        //public ushort ServerPort { get; set; }
        //public string UserId { get; set; }
        //public string Password { get; set; }

        public dl_files FileInfo { get; set; }

        public ILog Logger { get; set; }

        public IDownloadServer DownloadServer { get; set; }

        public ConsoleProgressBar ProgressBar { get; set; }

        public event UpdateDownloadProgressEventHandler UpdateDownloadProgress;
        public event FileDownloadCompletedEventHandler FileDownloadSuccess;
        public event FileDownloadCompletedEventHandler FileDownloadFail;
        public event ResetSessionEventHandler ResetSession;

        private System.Timers.Timer progressTimer;
        private long lastFileSize = 0;

        public DH_EVS_Downloader()
        {
            progressTimer = new System.Timers.Timer();
            progressTimer.Interval = 1000 * 60;
            progressTimer.Enabled = false;
            progressTimer.Elapsed += ProgressTimer_Elapsed;
        }

        public HResult Download(dl_files file)
        {
            HResult result = new HResult() { success = false };

            FileInfo = file;
            FileInfo.dl_progress = 0;

            try
            {
                //if (Login() > 0)
                //{
                DateTime startTime = file.video_start_time;
                DateTime endTime = file.video_end_time;

                if (startTime == endTime)
                {
                    result.message = "The start time is the same ad the end time(开始时间与结束时间相同)!";
                    FileInfo.error_log = result.message;
                    FinishDownload(false);
                    return result;
                }
                if (startTime > endTime)
                {
                    result.message = "The start time is greater than the end time(开始时间大于结束时间)!";
                    FileInfo.error_log = result.message;
                    FinishDownload(false);
                    return result;
                }
                //set stream type 设置码流类型
                EM_STREAM_TYPE streamType = (EM_STREAM_TYPE)(file.stream_type + 1);
                IntPtr pStream = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
                Marshal.StructureToPtr((int)streamType, pStream, true);
                DaHuaNetClient.SetDeviceMode(m_LoginID, EM_USEDEV_MODE.RECORD_STREAM_TYPE, pStream);

                if (!Directory.Exists(file.file_path))
                {
                    Directory.CreateDirectory(file.file_path);
                }

                string fileName = Path.Combine(file.file_path, file.file_name);

                m_DownloadPosCallBack = new fTimeDownLoadPosCallBack(DownLoadPosCallBack);

                FileInfo.dl_start_time = DateTime.Now;
                //FileInfo.file_path = fileName;

                System.IO.File.Delete(fileName);

                m_DownloadID = DaHuaNetClient.DownloadByTime(m_LoginID, Convert.ToInt32(file.channel_id), EM_QUERY_RECORD_TYPE.ALL, startTime, endTime, fileName, m_DownloadPosCallBack, IntPtr.Zero, null, IntPtr.Zero, IntPtr.Zero);
                if (IntPtr.Zero == m_DownloadID)
                {
                    result.success = false;
                    result.message = DaHuaNetClient.GetLastError();
                    Logger.Log("DaHuaNetClient.DownloadByTime Error: " + result.message);
                    //if (result.message == "获取连接Session信息")
                    //{
                    //    ResetSession?.Invoke(this, null);
                    //}
                    //else
                    //{
                    FileInfo.error_log = result.message;
                    FileInfo.state = 2;
                    FinishDownload(false);
                    //}
                }
                else
                {
                    progressTimer.Enabled = true;
                    result.success = true;
                }
            }
            catch (Exception ex)
            {
                result.success = false;
                result.message = ex.Message;
                FileInfo.error_log = ex.Message;
                FileInfo.state = 2;
                FinishDownload(false);
            }

            return result;
        }

        public void ResetSessionInfo(params object[] args)
        {
            if (args.Length == 2)
            {
                m_LoginID = (IntPtr)args[0];
                m_DeviceInfo = (NET_DEVICEINFO_Ex)args[1];
            }
        }

        private void ProgressTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (lastFileSize == FileInfo.file_size)
            {
                Logger.Log("DaHuaNetClient.DownloadByTime no response");
                Stop();
                FileInfo.error_log = "获取连接Session信息";
                FileInfo.state = 2;
                FinishDownload(false);
            }
            else
            {
                lastFileSize = FileInfo.file_size;
            }
        }

        private void DownLoadPosCallBack(IntPtr lPlayHandle, uint dwTotalSize, uint dwDownLoadSize, int index, NET_RECORDFILE_INFO recordfileinfo, IntPtr dwUser)
        {
            try
            {
                //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " dwTotalSize=" + dwTotalSize + " dwDownLoadSize=" + dwDownLoadSize);
                if (lPlayHandle == m_DownloadID)
                {
                    if ((int)dwDownLoadSize == -1)
                    {
                        FileInfo.dl_progress = 100;
                        FinishDownload(true);
                    }
                    else if ((int)dwDownLoadSize == -2)
                    {
                        FileInfo.error_log = DaHuaNetClient.GetLastError();
                        FinishDownload(false);
                    }
                    else
                    {
                        FileInfo.file_size = (Int64)dwDownLoadSize * 1024;

                        int diff = Convert.ToInt32((DateTime.Now - FileInfo.dl_start_time.Value).TotalSeconds);

                        if (dwDownLoadSize >= dwTotalSize)
                        {
                            FileInfo.dl_progress = 100;
                            UpdateDownloadProgress?.Invoke(this, FileInfo, diff);
                        }
                        else
                        {
                            if (diff > 0)
                            {
                                FileInfo.dl_speed = FileInfo.file_size / diff;
                            }
                            FileInfo.dl_progress = (int)(dwDownLoadSize * 100 / dwTotalSize);

                            UpdateDownloadProgress?.Invoke(this, FileInfo, diff);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string s = ex.Message;
            }
        }

        public HResult Stop()
        {
            HResult result = new HResult();

            try
            {
                result.success = DaHuaNetClient.StopDownload(m_DownloadID);

                if (!result.success)
                {
                    result.message = DaHuaNetClient.GetLastError();


                    Logger.Error("停止下载文件失败：" + (FileInfo == null ? "" : FileInfo.file_name) + " - " + result.message);
                }
                else
                {
                    Logger.Log("停止下载文件：" + (FileInfo == null ? "" : FileInfo.file_name));
                }
            }
            catch (Exception ex)
            {
                result.success = false;
                result.message = ex.Message;
            }

            return result;
        }

        public void FinishDownload(bool success)
        {
            progressTimer.Enabled = false;
            FileInfo.dl_end_time = DateTime.Now;
            FileInfo.state = (success ? 1 : 2);

            System.Threading.Thread.Sleep(1000 * 2);

            //Logout();

            if (success)
            {
                FileDownloadSuccess(this, FileInfo);
            }
            else
            {
                FileDownloadFail(this, FileInfo);
            }
        }

        //private int Login()
        //{
        //    m_DeviceInfo = new NET_DEVICEINFO_Ex();

        //    m_LoginID = NETClient.LoginWithHighLevelSecurity(this.ServerIP, this.ServerPort, this.UserId, this.Password, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo);

        //    if (IntPtr.Zero == m_LoginID)
        //    {
        //        FileInfo.error_log = NETClient.GetLastError();
        //    }

        //    return m_LoginID.ToInt32();
        //}

        //private void Logout()
        //{
        //    try
        //    {
        //        bool result = NETClient.Logout(m_LoginID);
        //    }
        //    catch { }
        //}
    }
}
